package com.kellycheung.chicken_go_go;

import java.util.HashMap;

import com.kellycheung.chicken_go_go.GMediaPlayer.GMPType;

import android.graphics.Matrix;

public class Chicken extends GameObject {
	public enum ChickenStatus {
		normal(100), run(101), jump(102), collided(103), fly(104), fall(105)
		,getCoin(201), getItem(202)
		,win(301), lose(302)
		;
		
		private final int iVal;
		
		ChickenStatus( int p_iVal ) {
			this.iVal = p_iVal;
		}
		
		public int getValue() {
			return this.iVal;
		}
		
		public static boolean isAllowRun( ChickenStatus p_cs ) {
			switch ( p_cs ) {
			case collided:
				return false;
			default:
				return true;
			}
		}
	}
	
	protected final static float F_DEF_JUMP_SPEED = -20f;
	protected final static int F_DEF_JUMP_HIGHER_LIMIT = 10;
	protected final static float F_DEF_GRAVITY = 0.8f;
	protected final static float F_DEF_JUMP_HIGHER_ACC = -0.2f;
	
	protected final static float F_DEF_MAX_X_SPEED = 20f;
	protected final static float F_DEF_X_ACC_INC = 1f;
	protected final static float F_DEF_X_ACC_DEC = -0.5f;
	
	protected GPosition gpMovement;
	protected int[] iAllowJumpDelay;
	
	protected HashMap<String,Integer> mStatusAni;
	
	protected int iAllowJumpCnt;
	protected int iJumpCnt;
	protected int iJumpDelayCnt;
	protected int iJumpHigher;
	protected boolean bJumpHigher;
	protected boolean bMove;
	protected ChickenStatus csStatus;
	
	public Chicken( GameScene p_gsScene, int p_iZOrder ) {
		this( p_gsScene , p_iZOrder , GOAnchor.Down , 0f , 0f );
	}
	
	public Chicken( GameScene p_gsScene, int p_iZOrder , GOAnchor p_goa , float p_fX , float p_fY ) {
		super( p_gsScene , p_iZOrder , p_goa , p_fX , p_fY );
		
		try {
			this.iAllowJumpCnt = 1;
			this.iAllowJumpDelay = new int[3];
			this.iAllowJumpDelay[0] = 10;
			this.iJumpCnt = 0;
			this.iJumpDelayCnt = 0;
			this.iJumpHigher = 0;
			this.bJumpHigher = false;
			this.csStatus = ChickenStatus.normal;
			this.mStatusAni = new HashMap<String,Integer>();
			this.setMovement();
        } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void destroy() {
		try {
			if ( this.mStatusAni != null ) {
				this.mStatusAni.clear();
				this.mStatusAni = null;
			}
			
			this.gpMovement = null;
			this.iAllowJumpDelay = null;
			
			super.destroy();
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public int addAnimation( ChickenStatus p_cs , int[] p_iResId ) {
		try {
			return this.addAnimation( p_cs , p_iResId , 0 , null );
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.addAnimation(ChickenStatus,int[])" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return 0;
	}
	
	public int addAnimation( ChickenStatus p_cs , int[] p_iResId , int p_iFPS ) {
		try {
			return this.addAnimation( p_cs , p_iResId , p_iFPS , null );
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.addAnimation(ChickenStatus,int[],int)" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return 0;
	}
	
	public int addAnimation( ChickenStatus p_cs , int[] p_iResId , Matrix p_mRotator ) {
		try {
			return this.addAnimation( p_cs , p_iResId , 0 , p_mRotator );
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.addAnimation(ChickenStatus,int[],Matrix)" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return 0;
	}
	
	public int addAnimation( ChickenStatus p_cs , int[] p_iResId , int p_iFPS , Matrix p_mRotator ) {
		try {
			int iNewAniIdx = this.addAnimation( p_iResId , p_iFPS , p_mRotator ) ;
			
			this.mStatusAni.put( p_cs.name() , (iNewAniIdx-1) );
			
			return iNewAniIdx;
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.addAnimation(ChickenStatus,int[],int,Matrix)" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return 0;
	}
	
	public float getXDisplacement() {
		try {
			return this.gpMovement.gcThis.fX - this.gcCoord.fX;
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.getXDisplacement" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return 0;
	}
	
	public void jump() {
		try {
			if ( this.isAllowRun() && ChickenStatus.isAllowRun( this.csStatus ) ) {
				if ( this.iJumpCnt < this.iAllowJumpCnt ) {
					if ( this.iJumpDelayCnt == 0 ) {
						this.gpMovement.setYSpeed( Chicken.F_DEF_JUMP_SPEED );
						this.gpMovement.setYAcc( Chicken.F_DEF_GRAVITY , false );
						
						this.iJumpDelayCnt = this.iAllowJumpDelay[ this.iJumpCnt ];
						this.iJumpCnt++;
						this.iJumpHigher = 0;
						this.csStatus = ChickenStatus.jump;
					}
				}
			}
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.jump" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void jumpHigher() {
		try {
			if ( this.isAllowRun() && ChickenStatus.isAllowRun( this.csStatus ) ) {
				if ( this.iJumpCnt > 0 ) {
					if ( this.iJumpHigher < Chicken.F_DEF_JUMP_HIGHER_LIMIT ) {
						
						this.iJumpHigher++;
						this.bJumpHigher = true;
					}
				}
			}
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.jumpHigher" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void move( boolean p_bIsMove ) {
		try {
			if ( this.isAllowRun() && ChickenStatus.isAllowRun( this.csStatus ) ) {
				if ( p_bIsMove ) {
					this.gsScene.geMain.gmpPlayer.playMusic( GMPType.soundEffect , R.raw.run );
					if ( this.gcCoord.fY >= ((GameRacing)this.gsScene).fGroundLv ) {
						this.gpMovement.setXAcc( Chicken.F_DEF_X_ACC_INC , true );
					}
				} else {
					this.gsScene.geMain.gmpPlayer.pauseMusic( GMPType.soundEffect , R.raw.run );
					if ( this.gpMovement.fXSpeed > 0 ) {
						this.gpMovement.setXAcc( Chicken.F_DEF_X_ACC_DEC , true );
					}
				}
				
				//this.playAnimation( p_bIsMove );
				if ( this.gcCoord.fY >= ((GameRacing)this.gsScene).fGroundLv ) {
					if ( p_bIsMove ) {
						this.csStatus = ChickenStatus.run;
					}
					else {
						this.csStatus = ChickenStatus.normal;
					}
				}
			}
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.move" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	@Override
	public void preGameLoopLogic() {
		try {
			if ( this.isAllowRun() ) {
				if ( this.iAniIdx != this.mStatusAni.get( this.csStatus.name() ) ) {
					this.setAnimation( this.mStatusAni.get( this.csStatus.name() ) );
					this.playAnimation( true );
				}
				
				/*if ( this.gpMovement.fXSpeed < 0 ) {
					this.gpMovement.fXAcc = 0;
					this.gpMovement.fXSpeed = 0;
				}*/
				
				if ( ChickenStatus.isAllowRun( this.csStatus ) ) {
					this.gpMovement.toNewPoint();
				
					if ( this.bJumpHigher == true ) {
						this.gpMovement.setYAcc( Chicken.F_DEF_JUMP_HIGHER_ACC , false );
					}
					
					this.setCoord( this.gcCoord.fX , this.gpMovement.gcThis.fY );
					
					if ( this.iJumpCnt > 0 ) {
						if ( this.gcCoord.fY >= ((GameRacing)this.gsScene).fGroundLv ) {
							this.iJumpCnt = 0;
							this.iJumpDelayCnt = 0;
							this.iJumpHigher = 0;
							this.bJumpHigher = false;
							this.csStatus = ChickenStatus.normal;
							//this.iAniIdx = ChickenStatus.normal.getValue();
							this.gpMovement.setYSpeed( 0f );
							this.gpMovement.setYAcc( 0f , false );
							this.setCoord( this.gcCoord.fX , ((GameRacing)this.gsScene).fGroundLv );
						}
						else {
							if ( this.iJumpDelayCnt > 0 ) {
								this.iJumpDelayCnt--;
							}
						}
					}
					
					if ( this.bJumpHigher == true ) {
						this.bJumpHigher = false;
						this.gpMovement.setYAcc( Chicken.F_DEF_GRAVITY , false );
					}
				}
				else if ( this.playLoopCnt() > 3 ) {
					this.csStatus = ChickenStatus.normal;
					this.resetLoopCnt();
				}
			}
			
			super.preGameLoopLogic();
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.preGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void setMovement() {
		try {
			this.gpMovement = new GPosition( this.gcCoord );
			this.gpMovement.setXSpeedMax( Chicken.F_DEF_MAX_X_SPEED );
			this.gpMovement.setYSpeedMax( Chicken.F_DEF_JUMP_SPEED );
	    } catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "Chicken.setMovement" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public String toString() {
		return "L:" + String.valueOf(((GameRacing)this.gsScene).fGroundLv)
				+ " - J:" + String.valueOf(this.iJumpCnt) + "(D:" + String.valueOf(this.iJumpDelayCnt) + ",H:" + String.valueOf(this.iJumpHigher) + ")"
				+ " - C:" + this.gcCoord.toString();
	}
}
